/**
 * ImgCodeServlet
 *
 * @author WS
 * @date 2020/03/11
 */
package com.study.experiment04.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet(name = "imgCode", urlPatterns = "/experiment04/img/imgCode")
public class ImgCodeServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("image/jpeg");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        int width = 60;
        int height = 30;
        int length = 4;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        String checkCode = getImage(image, width,
                height, length);
        request.getSession().setAttribute("ValidateCode", checkCode);
        try {
            ImageIO.write(image, "JPEG", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        response.flushBuffer();
    }

    /**
     * 随机取一个颜色Color对象
     */
    Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    /**
     * 创建BufferedImage对象,并返回图片中的数据（字符串）
     *
     * @param image 对象
     * @param    width 图像宽度
     * @param    height 图像高度
     * @param    length 字符串长度
     */
    private String getImage(BufferedImage image, int width,
                            int height, int length) {
        // 可用的随机编码字码，可以用字符串表示，相应地用charAt(int index)方法取得某一字符。
        char[] code = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
                'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
                'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
        // 可用的字体
        String[] Fonts = {"Times New Roman",
                "Verdana",
                "Arial Narrow",
                "Candara",
                "Californian FB",
                "Brush Script MT"
        };

        // 获取图形上下文
        Graphics g = image.getGraphics();
        // 生成随机类对象
        Random random = new Random();
        // 画边框
        g.fillRect(0, 0, width, height);
        // 选择颜色, 设定背景色
        g.setColor(getRandColor(160, 200));
        // 随机产生155条干扰线，使图象中的认证码不易被其它程序探测到
        for (int i = 0; i < 155; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            //画随机线条
            g.drawLine(x, y, x + xl, y + yl);
        }
        // 保存随机产生的验证码字符。
        String sRand = "";
        int t;
        // 取随机产生的验证码(字符长度由length指定)
        for (int i = 0; i < length; i++) {
            t = random.nextInt(code.length);
            //随机选择一个字符
            String rand = "" + code[t];
            sRand += rand;
            //随机选择颜色
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            //随机选择字体，字体大小为（25+random.nextInt(5)）
            g.setFont(new Font(Fonts[random.nextInt(5)], Font.PLAIN, 25 + random.nextInt(5)));
            //在(13*i,15+random.nextInt(10))位置写一个字符，将验证码显示到图象中
            g.drawString(rand, 13 * i + 6, 15 + random.nextInt(10));
        }
        // 释放图形上下文
        g.dispose();
        // 返回验证码
        return sRand;
    }
}
